home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 2001 May / SGI Freeware 2001 May - Disc 1.iso / dist / fw_teTeX.idb / usr / freeware / bin / epstopdf.z / epstopdf
Text File  |  2001-01-10  |  8KB  |  283 lines

  1. eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' && eval 'exec perl -S $0 $argv:q'
  2.   if 0;
  3. use strict;
  4.  
  5. # Change by Thomas Esser, Sept. 1998: The above lines allows us to find
  6. # perl along $PATH rather than guessing a fixed location. The above
  7. # construction should work with most shells.
  8.  
  9. # A script to transform an EPS file so that:
  10. #   a) it is guaranteed to start at the 0,0 coordinate
  11. #   b) it sets a page size exactly corresponding to the BoundingBox
  12. # This means that when Ghostscript renders it, the result needs no
  13. # cropping, and the PDF MediaBox is correct.
  14. #   c) the result is piped to Ghostscript and a PDF version written
  15. #
  16. # It needs a Level 2 PS interpreter.
  17. # If the bounding box is not right, of course, you have problems...
  18. #
  19. # The only thing I have not allowed for is the case of
  20. # "%%BoundingBox: (atend)", which is more complicated.
  21. #
  22. # Sebastian Rahtz, for Elsevier Science
  23. #
  24. # now with extra tricks from Hans Hagen's texutil.
  25. #
  26. # History
  27. #  1999/05/06 v2.5 (Heiko Oberdiek)
  28. #    * New options: --hires, --exact, --filter, --help.
  29. #    * Many cosmetics: title, usage, ...
  30. #    * New code for debug, warning, error
  31. #    * Detecting of cygwin perl
  32. #    * Scanning for %%{Hires,Exact,}BoundingBox.
  33. #    * Scanning only the header in order not to get a wrong
  34. #      BoundingBox of an included file.
  35. #    * (atend) supported.
  36. #    * uses strict; (earlier error detecting).
  37. #    * changed first comment from '%!PS' to '%!';
  38. #    * corrected (atend) pattern: '\s*\(atend\)'
  39. #    * using of $bbxpat in all BoundingBox cases,
  40. #      correct the first white space to '...Box:\s*$bb...'
  41. #    * corrected first line (one line instead of two before 'if 0;';
  42. #
  43.  
  44. ### program identification
  45. my $program = "epstopdf";
  46. my $filedate="1999/05/06";
  47. my $fileversion="2.5";
  48. my $copyright = "Copyright 1998,1999 by Sebastian Rahtz et al.";
  49. my $title = "\U$program\E $fileversion, $filedate - $copyright\n";
  50.  
  51. ### ghostscript command name
  52. my $GS = "gs";
  53. $GS = "gswin32c" if $^O eq 'MSWin32';
  54. $GS = "gswin32c" if $^O =~ /cygwin/;
  55.  
  56. ### options
  57. $::opt_help=0;
  58. $::opt_debug=0;
  59. $::opt_compress=1;
  60. $::opt_gs=1;
  61. $::opt_hires=0;
  62. $::opt_exact=0;
  63. $::opt_filter=0;
  64. $::opt_outfile="";
  65.  
  66. ### usage
  67. my @bool = ("false", "true");
  68. my $usage = <<"END_OF_USAGE";
  69. ${title}Syntax:  $program [options] <eps file>
  70. Options:
  71.   --help:           print usage
  72.   --outfile=<file>: write result to <file>
  73.   --(no)filter:     read standard input   (default: $bool[$::opt_filter])
  74.   --(no)gs:         run ghostscript       (default: $bool[$::opt_gs])
  75.   --(no)compress:   use compression       (default: $bool[$::opt_compress])
  76.   --(no)hires:      scan HiresBoundingBox (default: $bool[$::opt_hires])
  77.   --(no)exact:      scan ExactBoundingBox (default: $bool[$::opt_exact])
  78.   --(no)debug:      debug informations    (default: $bool[$::opt_debug])
  79. Examples for producing 'test.pdf':
  80.   * $program test.eps
  81.   * produce postscript | $program --filter >test.pdf
  82.   * produce postscript | $program -f -d -o=test.pdf
  83. Example: look for HiresBoundingBox and produce corrected PostScript:
  84.   * $program -d --nogs -hires test.ps>testcorr.ps 
  85. END_OF_USAGE
  86.  
  87. ### process options
  88. use Getopt::Long;
  89. GetOptions (
  90.   "help!",
  91.   "debug!",
  92.   "filter!",
  93.   "compress!",
  94.   "gs!",
  95.   "hires!",
  96.   "exact!",
  97.   "outfile=s",
  98. ) or die $usage;
  99.  
  100. ### help functions
  101. sub debug {
  102.   print STDERR "* @_\n" if $::opt_debug;
  103. }
  104. sub warning {
  105.   print STDERR "==> Warning: @_!\n";
  106. }
  107. sub error {
  108.   die "$title!!! Error: @_!\n";
  109. }
  110. sub errorUsage {
  111.   die "$usage\n!!! Error: @_!\n";
  112. }
  113.  
  114. ### option help
  115. die $usage if $::opt_help;
  116.  
  117. ### get input filename
  118. my $InputFilename = "";
  119. if ($::opt_filter) {
  120.   @ARGV == 0 or 
  121.     die errorUsage "Input file cannot be used with filter option";
  122.   $InputFilename = "-";
  123.   debug "Input file: standard input";
  124. }
  125. else {
  126.   @ARGV > 0 or die errorUsage "Input filename missing";
  127.   @ARGV < 2 or die errorUsage "Unknown option or too many input files";
  128.   $InputFilename = $ARGV[0];
  129.   -f $InputFilename or error "'$InputFilename' does not exist";
  130.   debug "Input filename:", $InputFilename;
  131. }
  132.  
  133. ### option compress
  134. my $GSOPTS = "";
  135. $GSOPTS = "-dUseFlateCompression=false " unless $::opt_compress;
  136.  
  137. ### option BoundingBox types
  138. my $BBName = "%%BoundingBox:";
  139. !($::opt_hires and $::opt_exact) or
  140.   error "Options --hires and --exact cannot be used together";
  141. $BBName = "%%HiresBoundingBox:" if $::opt_hires;
  142. $BBName = "%%ExactBoundingBox:" if $::opt_exact;
  143. debug "BoundingBox comment:", $BBName;
  144.  
  145. ### option outfile
  146. my $OutputFilename = $::opt_outfile;
  147. if ($OutputFilename eq "") {
  148.   if ($::opt_gs) {
  149.     $OutputFilename = $InputFilename;
  150.     if (!$::opt_filter) {
  151.       $OutputFilename =~ s/\.[^\.]*$//;
  152.       $OutputFilename .= ".pdf";
  153.     }
  154.   }
  155.   else {
  156.     $OutputFilename = "-"; # standard output
  157.   }
  158. }
  159. if ($::opt_filter) {
  160.   debug "Output file: standard output";
  161. }
  162. else {
  163.   debug "Output filename:", $OutputFilename;
  164. }
  165.  
  166. ### option gs
  167. if ($::opt_gs) {
  168.   debug "Ghostscript command:", $GS;
  169.   debug "Compression:", ($::opt_compress) ? "on" : "off";
  170. }
  171.  
  172. ### open input file
  173. open(IN,"<$InputFilename") or error "Cannot open", 
  174.   ($::opt_filter) ? "standard input" : "'$InputFilename'";
  175. binmode IN;
  176.  
  177. ### open output file
  178. if ($::opt_gs) {
  179.   my $pipe = "$GS -q -sDEVICE=pdfwrite $GSOPTS " .
  180.           "-sOutputFile=$OutputFilename - -c quit";
  181.   debug "Ghostscript pipe:", $pipe;
  182.   open(OUT,"|$pipe") or error "Cannot open Ghostscript for piped input";
  183. }
  184. else {
  185.   open(OUT,">$OutputFilename") or error "Cannot write '$OutputFilename";
  186. }
  187.  
  188. ### scan first line
  189. my $header = 0;
  190. $_ = <IN>;
  191. if (/%!/) {
  192.   # throw away binary junk before %!
  193.   s/(.*)%!/%!/o;
  194. }
  195. $header = 1 if /^%/;
  196. debug "Scanning header for BoundingBox";
  197. print OUT;
  198.  
  199. ### variables and pattern for BoundingBox search
  200. my $bbxpatt = '[0-9eE\.\-]';
  201.                # protect backslashes: "\\" gets '\'
  202. my $BBValues = "\\s*($bbxpatt+)\\s+($bbxpatt+)\\s+($bbxpatt+)\\s+($bbxpatt+)";
  203. my $BBCorrected = 0;
  204.  
  205. sub CorrectBoundingBox {
  206.   my ($llx, $lly, $urx, $ury) = @_;
  207.   debug "Old BoundingBox:", $llx, $lly, $urx, $ury;
  208.   my ($width, $height) = ($urx - $llx, $ury - $lly);
  209.   my ($xoffset, $yoffset) = (-$llx, -$lly);
  210.   debug "New BoundingBox: 0 0", $width, $height;
  211.   debug "Offset:", $xoffset, $yoffset;
  212.  
  213.   print OUT "%%BoundingBox: 0 0 $width $height\n";
  214.   print OUT "<< /PageSize [$width $height] >> setpagedevice\n";
  215.   print OUT "gsave $xoffset $yoffset translate\n";
  216. }
  217.  
  218. ### scan header
  219. if ($header) {
  220.   while (<IN>) {
  221.  
  222.     ### end of header
  223.     if (!/^%/ or /^%%EndComments/) {
  224.       print OUT;
  225.       last;
  226.     }
  227.  
  228.     ### BoundingBox with values
  229.     if (/^$BBName$BBValues/) {
  230.       CorrectBoundingBox $1, $2, $3, $4;
  231.       $BBCorrected = 1;
  232.       last;
  233.     }
  234.  
  235.     ### BoundingBox with (atend)
  236.     if (/^$BBName\s*\(atend\)/) {
  237.       debug $BBName, "(atend)";
  238.       if ($::opt_filter) {
  239.         warning "Cannot look for BoundingBox in the trailer",
  240.                 "with option --filter";
  241.         last;
  242.       }
  243.       my $pos = tell(IN);
  244.       debug "Current file position:", $pos;
  245.  
  246.       # looking for %%BoundingBox
  247.       while (<IN>) {
  248.         # skip over included documents
  249.         if (/^%%BeginDocument/) {
  250.           while (<IN>) {
  251.             last if /^%%EndDocument/;
  252.           }
  253.         }
  254.         if (/^$BBName$BBValues/) {
  255.           CorrectBoundingBox $1, $2, $3, $4;
  256.           $BBCorrected = 1;
  257.           last;
  258.         }
  259.       }
  260.  
  261.       # go back
  262.       seek(IN, $pos, 0) or error "Cannot go back to line '$BBName (atend)'";
  263.       last;
  264.     }
  265.     
  266.     # print header line
  267.     print OUT;
  268.   }
  269. }
  270.  
  271. ### print rest of file
  272. while (<IN>) {
  273.   print OUT;
  274. }
  275.  
  276. ### close files
  277. close(IN);
  278. print OUT "grestore\n" if $BBCorrected;
  279. close(OUT);
  280. warning "BoundingBox not found" unless $BBCorrected;
  281. debug "Ready.";
  282. ;
  283.